package cn.lcp.fcct;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

public class CodeFactory {
    public static CodeFactory instance;
    private static Boolean FLAG ;
    private static String name;
    private static String moudle;
    private static String table;
    private static String tablePkg;
    private static List<String> tableList;
    private static String code_package ;
    private static String moudle_code_package ;
    private static String resource_code_package ;
    private static String moudle_resource_code_package ;
    private static String interface_code_package ;
    private static String interface_code_package_bo ;
    private static String interface_code_package_vo ;
    @SuppressWarnings("unused")
	private static String interface_code_package_unit ;
    private static String srv_code_package ;
    private static String small_code_package ;
    private static String app_code_package ;
    private static List<String> codeTemplates = new ArrayList<>();
    private static List<String> preCodeTemplates = new ArrayList<>();
    private static List<String> files = new ArrayList<>();
    private static Boolean excludeFirstParamater;
    private static List<String> excludefiles = new ArrayList<>();
    private static List<String> exclude_fileds = new ArrayList<>();

    private CodeFactory(){}
    public static CodeFactory getInstance(){
        if(instance == null){
            instance = new CodeFactory();
            try {
                Properties properties = new Properties();
                FileInputStream in = new FileInputStream("CodeTemplates/CodeTemplates.properties");
                properties.load(in);
                in.close();
                FLAG = Boolean.parseBoolean(properties.getProperty("COVER_FLAG").trim());
                name = properties.getProperty("name").trim();
                moudle = properties.getProperty("moudle").trim();
                table = properties.getProperty("table").trim();
                tablePkg = properties.getProperty("tablePkg").trim();
                code_package = properties.getProperty("CODE_PACKAGE").trim() + moudle + "/";
                moudle_code_package = "../" + name + "-" + moudle + "/" + code_package;
                resource_code_package = properties.getProperty("resource_CODE_PACKAGE").trim() + moudle + "/";
                moudle_resource_code_package = "../" + name + "-" + moudle + "/" + resource_code_package;
                interface_code_package = properties.getProperty("interface_CODE_PACKAGE").trim();
                interface_code_package_bo = interface_code_package + "bo/" + moudle + "/";
                interface_code_package_vo = interface_code_package + "vo/" + moudle + "/";
                interface_code_package_unit = interface_code_package + "unit/" + moudle + "/";
                srv_code_package = properties.getProperty("srv_CODE_PACKAGE").trim() + moudle + "/";
                small_code_package = properties.getProperty("small_CODE_PACKAGE").trim() + moudle + "/";
                app_code_package = properties.getProperty("app_CODE_PACKAGE").trim() + moudle + "/";
                
                
                String[] tableStrList = table.split(",");
                tableList = new ArrayList<>();
                for (String tb : tableStrList) {
                	tableList.add(tb);
                }
                
                excludeFirstParamater = Boolean.parseBoolean(properties.getProperty("EXCLUDE_FIRST_PARAMATER").trim());
                for (String exclude_file:properties.getProperty("EXCLUDE_FILES").trim().split(",")) {
                    excludefiles.add(exclude_file); 
                }
                for (String exclude_filed:properties.getProperty("EXCLUDE_FILEDS").trim().split(",")) {
                    exclude_fileds.add(exclude_filed);
                }
                for (String code_templates_folder:properties.getProperty("TEMPLATES").trim().split(",")) {
                    switch (code_templates_folder){
                        case "po":
                            codeTemplates.add("Po.java");
                            preCodeTemplates.add("");
                            files.add(moudle_code_package+"db/entity/");
                            break;
                        case "createBo":
                        	codeTemplates.add("CreateBo.java");
                        	preCodeTemplates.add("Create");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "deleteBo":
                        	codeTemplates.add("DeleteBo.java");
                        	preCodeTemplates.add("Delete");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "detailBo":
                        	codeTemplates.add("DetailBo.java");
                        	preCodeTemplates.add("Detail");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "searchBo":
                        	codeTemplates.add("SearchBo.java");
                        	preCodeTemplates.add("Search");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "updateBo":
                        	codeTemplates.add("UpdateBo.java");
                        	preCodeTemplates.add("Update");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "startBo":
                        	codeTemplates.add("StartBo.java");
                        	preCodeTemplates.add("Start");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "stopBo":
                        	codeTemplates.add("StopBo.java");
                        	preCodeTemplates.add("Stop");
                        	files.add(interface_code_package_bo);
                        	break;
                        case "listVo":
                        	codeTemplates.add("ListVo.java");
                        	preCodeTemplates.add("List");
                        	files.add(interface_code_package_vo);
                        	break;
                        case "detailVo":
                        	codeTemplates.add("DetailVo.java");
                        	preCodeTemplates.add("Detail");
                        	files.add(interface_code_package_vo);
                        	break;
                        case "mapper":
                            codeTemplates.add("Mapper.java");
                            preCodeTemplates.add("");
                            files.add(moudle_code_package+"db/dao/gen/");
                            break;
                        case "dao":
                        	codeTemplates.add("Dao.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"db/dao/ext/");
                        	break;
                        case "mapperXml":
                        	codeTemplates.add("Mapper.xml");
                        	preCodeTemplates.add("");
                        	files.add(moudle_resource_code_package+"db/dao/gen/");
                        	break;
                        case "daoXml":
                        	codeTemplates.add("Dao.xml");
                        	preCodeTemplates.add("");
                        	files.add(moudle_resource_code_package+"db/dao/ext/");
                        	break;
                        case "read":
                        	codeTemplates.add("Read.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "create":
                        	codeTemplates.add("Create.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "delete":
                        	codeTemplates.add("Delete.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "update":
                        	codeTemplates.add("Update.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "start":
                        	codeTemplates.add("Start.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "stop":
                        	codeTemplates.add("Stop.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "check":
                        	codeTemplates.add("Check.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "export":
                        	codeTemplates.add("Export.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package+"processor/");
                        	break;
                        case "operateService":
                        	codeTemplates.add("OperateService.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "operateServiceExt":
                        	codeTemplates.add("OperateServiceExt.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "operateServiceApp":
                        	codeTemplates.add("OperateServiceApp.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "operateServiceWechat":
                        	codeTemplates.add("OperateServiceWechat.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "readService":
                        	codeTemplates.add("ReadService.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "readServiceExt":
                        	codeTemplates.add("ReadServiceExt.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "readServiceApp":
                        	codeTemplates.add("ReadServiceApp.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "readServiceWechat":
                        	codeTemplates.add("ReadServiceWechat.java");
                        	preCodeTemplates.add("");
                        	files.add(moudle_code_package);
                        	break;
                        case "operateController":
                        	codeTemplates.add("OperateController.java");
                        	preCodeTemplates.add("");
                        	files.add(srv_code_package);
                        	break;
                        case "readController":
                        	codeTemplates.add("ReadController.java");
                        	preCodeTemplates.add("");
                        	files.add(srv_code_package);
                        	break;
                        case "operateControllerApp":
                        	codeTemplates.add("OperateController.java");
                        	preCodeTemplates.add("");
                        	files.add(app_code_package);
                        	break;
                        case "readControllerApp":
                        	codeTemplates.add("ReadController.java");
                        	preCodeTemplates.add("");
                        	files.add(app_code_package);
                        	break;
                        case "operateControllerWechat":
                        	codeTemplates.add("OperateController.java");
                        	preCodeTemplates.add("");
                        	files.add(small_code_package);
                        	break;
                        case "readControllerWechat":
                        	codeTemplates.add("ReadController.java");
                        	preCodeTemplates.add("");
                        	files.add(small_code_package);
                        	break;
                        case "server":
                            codeTemplates.add("Service.java");
                            preCodeTemplates.add("");
                            files.add(moudle_code_package+"server/");
                            break;
                        case "serverImpl":
                            codeTemplates.add("ServiceImpl.java");
                            preCodeTemplates.add("");
                            files.add(moudle_code_package+"server/Impl/");
                            break;
                    }
                }
                for (String code_template:properties.getProperty("EXCLUDE_FILES").trim().split(",")) {
                    excludefiles.add(code_template);
                }
            }catch (IOException e){
                throw new RuntimeException("配置加载错误,请确认路径或参数是否正确!");
            }

        }
        return instance;
    }

    private Boolean excludeParamater(Integer index,String paramater){
        if(excludeFirstParamater&&index == 0){
            return false;
        }
        for (String excludefile:excludefiles) {
            if(excludefile.equals(paramater)){
                return false;
            }
        }
        return true;
    }

    private Boolean validateParamateNum(List<InformationSchema> informationSchemas,List<String> exclude_fileds){
        List<String> vpn = new ArrayList<>();
        for (int i = 0; i < informationSchemas.size(); i++) {
            if(excludeFirstParamater&&i==0){
                continue;
            }
            String columnName = informationSchemas.get(i).getColumnName();
            if(exclude_fileds.contains(columnName)){
                vpn.add(columnName);
            }
        }
        return vpn.size()!=1;
    }

    private String formatSqlParamater(String sqlParamater){
        String paramater = "";
        switch (sqlParamater){
            case "int":
                paramater = "Integer";
                break;
            case "bigint":
                paramater = "Long";
                break;
            case "varchar":
                paramater = "String";
                break;
            case "datetime":
                paramater = "Date";
                break;
            case "timestamp":
                paramater = "Date";
                break;
            case "longtext":
            	paramater = "String";
            	break;
            case "text":
            	paramater = "String";
            	break;
            case "double":
            	paramater = "Double";
            	break;
            case "decimal":
            	paramater = "BigDecimal";
            	break;
            case "float":
            	paramater = "Float";
            	break;
        }
        return paramater;
    }

    /**
     *
     * @param tableName 数据库表名
     * @param informationSchemas 表内相关属性
     *         columnName:列名 dataType:列类型 columnComment:列描述
     * @throws Exception
     */
    public void CreateCode(String tableName,List<InformationSchema> informationSchemas, String tableComment){
        if (codeTemplates.size() != files.size()) {
            throw new RuntimeException("templates.length != files.length");
        }
        
        if (!tableList.contains(tableName)) {
        	return;
        }
        
        VelocityContext context = new VelocityContext();
        Map<String, String> entity = getEntity(tableName,informationSchemas);
        System.out.println(entity.get("insertEntity"));
        String conversionTableName = entity.get("poEntity");
        String conversionTableNameLower = entity.get("poEntityLower");
        String tablePk = entity.get("tablePk");
        String moudle = entity.get("moudle");
        String serialUID = entity.get("serialUID");
        
        String resultMap = entity.get("resultMap");
        String baseColumnList = entity.get("baseColumnList");
        String baseColumnListValue = entity.get("baseColumnListValue");
        String insertSelective = entity.get("insertSelective");
        String insertSelectiveValue = entity.get("insertSelectiveValue");
        String updateSelective = entity.get("updateSelective");
        String update = entity.get("update");
        
        String baseColumnDetail = entity.get("baseColumnDetail");
        
        context.put("createEntity", entity.get("createEntity"));
        context.put("deleteEntity", entity.get("deleteEntity"));
        context.put("listAllEntity", entity.get("listAllEntity"));
        context.put("listByIdEntity", entity.get("listByIdEntity"));
        context.put("listByNameEntity", entity.get("listByNameEntity"));
        context.put("listEntity", entity.get("listEntity"));
        context.put("countListEntity", entity.get("countListEntity"));
        context.put("detailEntity", entity.get("detailEntity"));
        
        context.put("insertEntity",entity.get("insertEntity"));
        context.put("insertSelectiveEntity",entity.get("insertSelectiveEntity"));
        context.put("deleteByPrimaryKeyEntity",entity.get("deleteByPrimaryKeyEntity"));
        context.put("selectEntity",entity.get("selectEntity"));
        context.put("getEntity",entity.get("getEntity"));
        context.put("updateEntity",entity.get("updateEntity"));
        context.put("updateSelectiveEntity",entity.get("updateSelectiveEntity"));
        context.put("poEntity",conversionTableName);
        context.put("poEntityLower",conversionTableNameLower);
        context.put("moudle",moudle);
        context.put("tablePkg",tablePkg);
        context.put("table",tableName);
        context.put("tablePk", tablePk);
        context.put("serialUID",serialUID);
        
        // xml
        context.put("resultMap", resultMap);
        context.put("baseColumnList", baseColumnList);
        context.put("baseColumnListValue", baseColumnListValue);
        context.put("insertSelective", insertSelective);
        context.put("insertSelectiveValue", insertSelectiveValue);
        context.put("updateSelective", updateSelective);
        context.put("update", update);
        context.put("baseColumnDetail", baseColumnDetail);
        
        context.put("createBoParamaterEntity",entity.get("createBoParamaterEntity"));
        context.put("createBoParamaterGetSetEntity",entity.get("createBoParamaterGetSetEntity"));
        context.put("updateBoParamaterEntity",entity.get("updateBoParamaterEntity"));
        context.put("updateBoParamaterGetSetEntity",entity.get("updateBoParamaterGetSetEntity"));
        
        context.put("createProcessSetParam",entity.get("createProcessSetParam"));
        context.put("tableComment", tableComment.replace("表", ""));
        
        
        
        context.put("poParamaterEntity",entity.get("poParamaterEntity"));
        context.put("poParamaterGetSetEntity",entity.get("poParamaterGetSetEntity"));
        context.put("serviceEntity",entity.get("serviceEntity"));
        context.put("serviceImplEntity",entity.get("serviceImplEntity"));
        context.put("creatTime",new Date().toString());
        try{
            for (int i = 0; i < files.size(); i++) {
                Template template = Velocity.getTemplate("/CodeTemplates/"+codeTemplates.get(i), "UTF-8");
                File file = null;
                if ("Po.java".equals(codeTemplates.get(i))) {
                    file = new File(files.get(i) + preCodeTemplates.get(i) + conversionTableName + codeTemplates.get(i).substring(2));
                }else {
                	conversionTableNameLower = genSmall(new StringBuilder(conversionTableName));
                	String fileName = null;
                	if (codeTemplates.get(i).endsWith("Vo.java") || codeTemplates.get(i).endsWith("Bo.java")) {
                		fileName = files.get(i) + tablePkg + "/" + preCodeTemplates.get(i) + conversionTableName + (codeTemplates.get(i).endsWith("Vo.java") ? "Vo.java" : codeTemplates.get(i).endsWith("Bo.java") ? "Bo.java" : codeTemplates.get(i));
                	} else if (codeTemplates.get(i).endsWith("Ext.java") || codeTemplates.get(i).endsWith("Service.java")
                			|| codeTemplates.get(i).endsWith("App.java") || codeTemplates.get(i).endsWith("Wechat.java")) {
                		fileName = files.get(i) + tablePkg + "/" + preCodeTemplates.get(i) + conversionTableName + (codeTemplates.get(i));
                	} else if (codeTemplates.get(i).endsWith("Controller.java")) {
                		fileName = files.get(i) + preCodeTemplates.get(i) + conversionTableName + (codeTemplates.get(i));
                	} else {
                		fileName = files.get(i) + preCodeTemplates.get(i) + conversionTableName + (codeTemplates.get(i).endsWith("Vo.java") ? "Vo.java" : codeTemplates.get(i).endsWith("Bo.java") ? "Bo.java" : codeTemplates.get(i));
                	}
                    file = new File(fileName);
                }
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
                if (!FLAG && file.exists()) {
                    continue;
                }
                System.out.println(file.getAbsolutePath());
                FileWriter fileWriter = new FileWriter(file);
                template.merge(context, fileWriter);
                fileWriter.close();
            }
        }  catch (Exception e){
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unused")
	private Map<String,String> getEntity(String tableName,List<InformationSchema> informationSchemas){
        Map<String,String> map = new HashMap<>();
        StringBuilder poParamaterEntity = new StringBuilder();
        StringBuilder poParamaterGetSetEntity = new StringBuilder();
        StringBuilder insertEntity = new StringBuilder();
        StringBuilder insertSelectiveEntity = new StringBuilder();
        // StringBuilder insertEntity2 = new StringBuilder();
        StringBuilder updateEntity = new StringBuilder();
        StringBuilder updateSelectiveEntity = new StringBuilder();
        StringBuilder deleteByPrimaryKeyEntity = new StringBuilder();
        StringBuilder selectEntity = new StringBuilder();
        StringBuilder getEntity = new StringBuilder();
        StringBuilder serviceEntity = new StringBuilder();
        StringBuilder serviceImplEntity = new StringBuilder();
        
        StringBuilder createEntity = new StringBuilder();
        StringBuilder deleteEntity = new StringBuilder();
        StringBuilder listAllEntity = new StringBuilder();
        StringBuilder listByIdEntity = new StringBuilder();
        StringBuilder listByNameEntity = new StringBuilder();
        StringBuilder listEntity = new StringBuilder();
        StringBuilder countListEntity = new StringBuilder();
        StringBuilder detailEntity = new StringBuilder();
        
        
        StringBuilder resultMap = new StringBuilder();
        StringBuilder baseColumnList = new StringBuilder();
        StringBuilder baseColumnListValue = new StringBuilder();
        StringBuilder insertSelective = new StringBuilder();
        StringBuilder insertSelectiveValue = new StringBuilder();
        StringBuilder updateSelective = new StringBuilder();
        StringBuilder update = new StringBuilder();
        StringBuilder baseColumnDetail = new StringBuilder();
        
        
        StringBuilder createBoParamaterEntity = new StringBuilder();
        StringBuilder createBoParamaterGetSetEntity = new StringBuilder();
        StringBuilder updateBoParamaterEntity = new StringBuilder();
        StringBuilder updateBoParamaterGetSetEntity = new StringBuilder();
        
        StringBuilder createProcessSetParam = new StringBuilder();
        
        String[] ts = tableName.split("_");
        StringBuilder conversionTableName = new StringBuilder();
        for (String t:ts) {
            conversionTableName.append(t.substring(0,1).toUpperCase()+t.substring(1));
        }
        conversionTableName = new StringBuilder(conversionTableName.substring(1));
        //Dao
        String poIDName = "";
        String tableIDName = "";
        String poIDType = "";
        StringBuilder setSQL = new StringBuilder();
        setSQL.append("");
        Boolean vpn = validateParamateNum(informationSchemas, exclude_fileds);
        Boolean flag = false;
        Integer endCreateBoI = 0;
        Integer endUpdateBoI = 0;
        String tablePk = "";
        for (int i = 0; i < informationSchemas.size(); i++) {
            StringBuilder columnName = new StringBuilder();
            String cn = informationSchemas.get(i).getColumnName();
            String type = informationSchemas.get(i).getDataType();
            String xmlType = getType(type);
            String[] cs = cn.split("_");
            for (int j = 0; j < cs.length; j++) {
                if(j==0){
                    columnName.append(cs[j]);
                }else{
                    columnName.append(cs[j].substring(0,1).toUpperCase()).append(cs[j].substring(1));
                }
            }
            
            if (i == 0) {
            	tablePk = cn;
            }
            
            // xml
            if (i > 0) {
            	resultMap.append("\n    <result column=\"" + cn + "\" property=\"" + columnName + "\" jdbcType=\"" + xmlType.toUpperCase() + "\" />");
            }
            
            insertSelective.append("\n            <if test=\"" + columnName +  " != null\" >\n                " + cn + ",\n            </if>");
        	insertSelectiveValue.append("\n            <if test=\"" + columnName +  " != null\" >\n                #{" + columnName +  ",jdbcType=" + xmlType.toUpperCase() + "},\n            </if>");
            
            
            if (i == informationSchemas.size() - 1) {
            	baseColumnList.append("\n    " + cn);
                baseColumnListValue.append("\n            #{" + columnName + ",jdbcType=" + xmlType.toUpperCase() + "}");
            	
            	baseColumnDetail.append("\n            " + cn + " " + columnName);
            } else {
            	baseColumnList.append("\n    " + cn + ", ");
                baseColumnListValue.append("\n            #{" + columnName + ",jdbcType=" + xmlType.toUpperCase() + "}" + ", ");
            	
            	baseColumnDetail.append("\n            " + cn + " " + columnName + ", ");
            }
            
            updateSelective.append("\n    <if test=\"" + columnName +  " != null\" >\n        " + cn + " = #{" + columnName + ",jdbcType=" + xmlType.toUpperCase() + "}" + ",\n    </if>");
            
            if (i > 0 && i == informationSchemas.size() - 1) {
            	update.append("\n        " + cn + " = #{" + columnName + ",jdbcType=" + xmlType.toUpperCase() + "}");
            } else if (i > 0) {
            	update.append("\n        " + cn + " = #{" + columnName + ",jdbcType=" + xmlType.toUpperCase() + "}" + ",");
            }
            
            String poDataType = formatSqlParamater(type);
            
            if (i == 0) {
                poIDName = columnName.toString();
                tableIDName = cn;
                poIDType = poDataType;
            }
            
            //Po
            if(!exclude_fileds.contains(informationSchemas.get(i).getColumnName()) || "create_time".equals(informationSchemas.get(i).getColumnName())){
                poParamaterEntity.append("    private ").append(poDataType+" ").
                        append(columnName+";     //").append(informationSchemas.get(i).getColumnComment()+"\n\n");
                poParamaterGetSetEntity.append("    public ").append(poDataType+" ").
                        append("get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"() {\n        return ").
                        append(columnName+";\n    }").append("\n\n    public "+ "void" +" ").
                        append("set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"(").
                        append(poDataType+" ").
                        append(columnName+") {\n").append("        this."+columnName+" = "+columnName+";\n	}\n\n");
            }
            
            // createBo
            if ("creator".equals(columnName.toString())) {
            	++ endCreateBoI;
            }
            if (i > 0 && endCreateBoI.intValue() == 0) {
            	
            	if(!exclude_fileds.contains(informationSchemas.get(i).getColumnName())){
            			createBoParamaterEntity.append("    private ").append(poDataType+" ").
            			append(columnName+";     //").append(informationSchemas.get(i).getColumnComment()+"\n\n");
            			createBoParamaterGetSetEntity.append("    public ").append(poDataType+" ").
            			append("get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"() {\n        return ").
            			append(columnName+";\n    }").append("\n\n    public "+ "void" +" ").
            			append("set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"(").
            			append(poDataType+" ").
            			append(columnName+") {\n").append("        this."+columnName+" = "+columnName+";\n	}\n\n");
            	}
            }
            
            // updateBo
            if ("creator".equals(columnName.toString())) {
            	++ endUpdateBoI;
            }
            if (endUpdateBoI.intValue() == 0) {
            	
            	if(!exclude_fileds.contains(informationSchemas.get(i).getColumnName())){
            			updateBoParamaterEntity.append("    private ").append(poDataType+" ").
            			append(columnName+";     //").append(informationSchemas.get(i).getColumnComment()+"\n\n");
            			updateBoParamaterGetSetEntity.append("    public ").append(poDataType+" ").
            			append("get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"() {\n        return ").
            			append(columnName+";\n    }").append("\n\n    public "+ "void" +" ").
            			append("set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1)+"(").
            			append(poDataType+" ").
            			append(columnName+") {\n").append("        this."+columnName+" = "+columnName+";\n	}\n\n");
            	}
            }
            
            
            // create processor 
            if ("creator".equals(columnName.toString())) {
            	++ endUpdateBoI;
            }
            if (i > 0 && endUpdateBoI.intValue() == 0) {
            	
            	if(!exclude_fileds.contains(informationSchemas.get(i).getColumnName())){
            		createProcessSetParam.append("    	record.set" 
            				+ columnName.substring(0,1).toUpperCase()+columnName.substring(1) + "(param.get" 
            				+ columnName.substring(0,1).toUpperCase()+columnName.substring(1) + "());\n");
            	}
            }
            
            
            if(excludeParamater(i,cn)){
            	if (flag) {
            		continue;
            	}
                String conversionTableNameLower = genSmall(conversionTableName);
                if(!vpn||informationSchemas.size()==i+1){
                	// mapper
                	deleteByPrimaryKeyEntity.append("int deleteByPrimaryKey("+poIDType+" "+poIDName+");");
                    insertEntity.append("int insert("+conversionTableName+" "+ "record" +");");
                    insertSelectiveEntity.append("int insertSelective("+conversionTableName+" "+"record"+");");
                    selectEntity.append("" + conversionTableName+" selectByPrimaryKey(" + poIDType + " " + conversionTableNameLower + "Id);");
                    updateSelectiveEntity.append("int updateByPrimaryKeySelective("+conversionTableName+" "+"record"+");");
                    updateEntity.append("int updateByPrimaryKey("+conversionTableName+" "+"record"+");");
                    
                    // dao
                    createEntity.append("void create("+conversionTableName+" "+"record"+");");
                    deleteEntity.append("void delete("+conversionTableName+" "+"record"+");");
                    listAllEntity.append("List<" + conversionTableName + "> listAll();");
                    listByIdEntity.append("List<" + conversionTableName + "> listById(@Param(\"" + conversionTableNameLower + "IdList\") List<Long> " + conversionTableNameLower + "IdList);");
                    listByNameEntity.append("List<" + conversionTableName + "> listByName(@Param(\"" + "" + "name\") String " + "" + "name);");
                    listEntity.append("List<List" + conversionTableName + "Vo> list(Search" + conversionTableName + "Bo bo);");
                    countListEntity.append("Integer countList(Search" + conversionTableName + "Bo bo);");
                    detailEntity.append("Detail" + conversionTableName + "Vo detail(@Param(\"" + conversionTableNameLower + "Id\") Long "+ conversionTableNameLower+"Id);");
                    flag = true;
                    
                }
            }
        }
        
        
        
        map.put("createEntity", createEntity.toString());
        map.put("deleteEntity", deleteEntity.toString());
        map.put("listAllEntity", listAllEntity.toString());
        map.put("listByIdEntity", listByIdEntity.toString());
        map.put("listByNameEntity", listByNameEntity.toString());
        map.put("listEntity", listEntity.toString());
        map.put("countListEntity", countListEntity.toString());
        map.put("detailEntity", detailEntity.toString());
        
        map.put("insertEntity",insertEntity.toString());
        map.put("insertSelectiveEntity",insertSelectiveEntity.toString());
        map.put("updateEntity",updateEntity.toString());
        map.put("updateSelectiveEntity",updateSelectiveEntity.toString());
        map.put("deleteByPrimaryKeyEntity",deleteByPrimaryKeyEntity.toString());
        map.put("serviceEntity",serviceEntity.toString());
        map.put("getEntity",getEntity.toString());
        map.put("serviceImplEntity",serviceImplEntity.toString());
        map.put("selectEntity",selectEntity.toString());
        map.put("poParamaterEntity",poParamaterEntity.toString());
        map.put("poParamaterGetSetEntity",poParamaterGetSetEntity.toString());
        map.put("poEntity",conversionTableName.toString());
        String conversionTableNameLower = genSmall(new StringBuilder(conversionTableName));
        map.put("poEntityLower",conversionTableNameLower.toString());
        map.put("tablePk", tablePk);
        map.put("moudle", moudle);
        
        // xml
        map.put("resultMap", resultMap.toString());
        map.put("baseColumnList", baseColumnList.toString());
        map.put("baseColumnListValue", baseColumnListValue.toString());
        map.put("insertSelective", insertSelective.toString());
        map.put("insertSelectiveValue", insertSelectiveValue.toString());
        map.put("updateSelective", updateSelective.toString());
        map.put("update", update.toString());
        map.put("baseColumnDetail", baseColumnDetail.toString());
        
        map.put("createBoParamaterEntity",createBoParamaterEntity.toString());
        map.put("createBoParamaterGetSetEntity",createBoParamaterGetSetEntity.toString());
        map.put("updateBoParamaterEntity",updateBoParamaterEntity.toString());
        map.put("updateBoParamaterGetSetEntity",updateBoParamaterGetSetEntity.toString());
        
        map.put("createProcessSetParam",createProcessSetParam.toString());
        
        Long serialUID = (long)(Math.random() * 2000000000000000000L);
        map.put("serialUID", serialUID + "L");
        return  map;
    }
    
    private String getType(String type) {
    	switch (type) {
		case "int":
			return "INTEGER";
		case "datetime":
			return "TIMESTAMP";
		case "longtext":
			return "LONGVARCHAR";
		default:
			break;
		}
		return type;
	}
	private static String genSmall(StringBuilder conversionTableName) {
    	String conversionTableNameLower = conversionTableName.toString().substring(0,1).toLowerCase() + conversionTableName.toString().substring(1);
    	return conversionTableNameLower;
    }

}
